package com.cddx.logistics.service.impl;

import com.cddx.logistics.domain.dto.SysJobTimeQueryDTO;
import com.cddx.logistics.domain.pojo.StorageLocation;
import com.cddx.logistics.domain.pojo.SysAnnouncement;
import com.cddx.logistics.domain.pojo.SysJobtime;
import com.cddx.logistics.domain.vo.SysJobTimeVO;
import com.cddx.logistics.mapper.SysJobtimeMapper;
import com.cddx.logistics.service.StorageLocationService;
import com.cddx.logistics.service.SysAnnouncementService;
import com.cddx.logistics.service.SysJobtimeService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

@Service
public class SysJobtimeServiceImpl implements SysJobtimeService {
    @Autowired
    private SysJobtimeMapper sysJobtimeMapper;

    /**
     * 新增的内容
     */
    @Autowired
    private StorageLocationService storageLocationService;

    @Autowired
    private SysAnnouncementService sysAnnouncementService;

    //日志打印
    private static final Logger log = LoggerFactory.getLogger(SysJobtimeServiceImpl.class);

    @Scheduled(cron = "0 */5 * * * * ")
    public void checkOverfilledLocations() {
        log.info("开始检查库位...");
        List<StorageLocation> locations = storageLocationService.getAll();
        log.info("获取到库位数量：{}", locations.size());

        for (StorageLocation loc : locations) {
            synchronized (loc.getStorageLocationCode().intern()) { // 防止并发插入相同内容
                try {
                    checkAndSendWarning(loc);
                } catch (Exception e) {
                    log.error("处理库位 {} 时发生异常", loc.getStorageLocationCode(), e);
                }
            }
        }
    }

    private void checkAndSendWarning(StorageLocation loc) {
        if (loc.getStorageLocationUsedCapacity().compareTo(loc.getStorageLocationTotalCapacity()) >= 0) {
            return; // 已满或超限，跳过
        }

        BigDecimal used = loc.getStorageLocationUsedCapacity();
        BigDecimal total = loc.getStorageLocationTotalCapacity();
        double percent = used.divide(total, 4, RoundingMode.HALF_UP).doubleValue();

        String title = "库位即将超限";
        String content = loc.getStorageLocationName() + " 即将超限";

        if (percent >= 0.9) {
            if (loc.getLastWarnedAt() != null) {
                log.warn("库位 {} 已经预警过，跳过", loc.getStorageLocationCode());
                return;
            }

            boolean success = sendWarningAndMarkTime(loc, title, content);
            if (success) {
                log.info("已插入新公告，并记录最后预警时间：{}", loc.getStorageLocationCode());
            } else {
                log.warn("插入公告或更新预警时间失败：{}", loc.getStorageLocationCode());
            }
        } else {
            if (loc.getLastWarnedAt() != null) {
                loc.setLastWarnedAt(null);
                storageLocationService.update(loc);
                log.info("库位 {} 已恢复正常，清除最后预警时间", loc.getStorageLocationCode());
            }
        }
    }

    @Transactional
    public boolean sendWarningAndMarkTime(StorageLocation loc, String title, String content) {
        SysAnnouncement announcement = new SysAnnouncement();
        announcement.setTitile(title);
        announcement.setMsgContent(content);
        announcement.setSendTime(new Date());
        announcement.setSender("system");
        announcement.setSendStatus("1");
        announcement.setDelFlag("0");

        boolean inserted = sysAnnouncementService.addannounce(announcement, null);
        if (!inserted || announcement.getId() == null) {
            return false;
        }

        Integer anntId = announcement.getId();
        List<Integer> userIds = sysAnnouncementService.getAllUserIds(); // 获取所有用户 ID

        for (Integer userId : userIds) {
            sysAnnouncementService.insertSendRecord(userId, anntId, 0); // 插入未读状态
        }

        loc.setLastWarnedAt(LocalDateTime.now());
        return storageLocationService.update(loc);
    }

    @Override
    public boolean add(SysJobtime sysJobtime) {
       return sysJobtimeMapper.add(sysJobtime)>0;
    }

    @Override
    public boolean update(SysJobtime sysJobtime) {
        return sysJobtimeMapper.update(sysJobtime)>0;
    }

    @Override
    public boolean delete(Integer id) {
        return sysJobtimeMapper.deleteById(id)>0;
    }

    @Override
    public PageInfo<SysJobTimeVO> queryPage(SysJobTimeQueryDTO sysJobTimeQueryDTO) {
        PageHelper.startPage(sysJobTimeQueryDTO.getPage(),sysJobTimeQueryDTO.getLimit());
        List<SysJobTimeVO> sysJobTimeVOList = sysJobtimeMapper.queryPage(sysJobTimeQueryDTO);
        PageInfo<SysJobTimeVO> pageInfo = new PageInfo<>(sysJobTimeVOList);
        return pageInfo;
    }

    @Override
    public boolean updateStatus(Integer id, Integer jobStatus) {
        return sysJobtimeMapper.updateStatus(id,jobStatus)>0;
    }
}
